"""Support for Modbus switchs."""
from __future__ import annotations
import logging
import voluptuous as vol
from datetime import timedelta
import asyncio
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity
from homeassistant.const import (
    ATTR_TEMPERATURE,
    CONF_HOST,
    CONF_PORT,
    EVENT_HOMEASSISTANT_STOP,
    CONF_ADDRESS,
    
    CONF_NAME,
    CONF_SLAVE,
    CONF_UNIQUE_ID,
)
import homeassistant.helpers.config_validation as cv

_LOGGER = logging.getLogger(__name__)
DEFAULT_PORT = 8899
CONF_SWITCHS = 'switchs'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {
        vol.Required(CONF_HOST): cv.string,
        vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
        vol.Optional(CONF_NAME,default='xk'): cv.string,
        vol.Optional(CONF_SWITCHS): vol.All(cv.ensure_list,[{
            vol.Required(CONF_NAME): cv.string,
            vol.Required(CONF_UNIQUE_ID): cv.string,
            vol.Required(CONF_ADDRESS): cv.positive_int,
            vol.Required(CONF_SLAVE): cv.positive_int,
        }]),
    }
)



from .modbus import (ModbusApp)
async def async_setup_platform(hass, config, add_entities, discovery_info=None):
    """modbus继电器配配置"""
    host = config.get(CONF_HOST)
    port = config.get(CONF_PORT)
    lights = config.get(CONF_SWITCHS)
    app = ModbusApp(host,port,hass,lights)
    await app.start_hub()

    devices = [ ModbusPlatform(app,entry[CONF_SLAVE],entry[CONF_ADDRESS],entry[CONF_NAME],entry[CONF_UNIQUE_ID]) for entry in lights]

    add_entities(devices)

    async def async_stop_app(e):
        await app.stop() 
        _LOGGER.warning('TcpToSerialClient stop')
        
    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, async_stop_app)
    return True

class ModbusPlatform(SwitchEntity):
    """Base for readonly platforms."""

    def __init__(self, hub, slave,address,name,unique_id) -> None:
        self._hub = hub
        self._name = name
        self._slave = int(slave)
        self._address = int(address)
        self._available = False
        self._unique_id = unique_id
        self._scan_interval = 10
        self._call_active = False
        self._is_on = True
        self._hub.add_callback(self.async_callback)

    def async_callback(self,data,slave):
        """Virtual function to be overwritten."""
        if self._slave != slave:
            return

        if not self._available:
            self._available = True

        if data[self._address] != self._is_on:
            self._is_on = data[self._address]
            self.async_write_ha_state()


    async def async_base_added_to_hass(self):
        _LOGGER.error('loading')
        pass

    @property
    def name(self):
        """Return the name of the sensor."""
        return self._name
    @property
    def unique_id(self):
        return self._unique_id

    @property
    def available(self) -> bool:
        """Return True if entity is available."""
        return self._available

    async def async_added_to_hass(self):
        """Handle entity which will be added."""
        pass

    @property
    def is_on(self):
        """Return true if switch is on."""
        return self._is_on

    async def async_turn(self, command):
        """Evaluate switch result."""
        await self._hub.write_cmd(self._slave,self._address,command)
        self._is_on = command
        #_LOGGER.error(command)
        self.async_write_ha_state()

    async def async_turn_off(self, **kwargs):
        """Set switch off."""
        await self.async_turn(False)
    
    async def async_turn_on(self, **kwargs):
        """Set switch off."""
        await self.async_turn(True)

   